#include "Clase.h"
#include <string.h>
#include <sstream>
Clase::Clase(std::string descripcion, unsigned int codigo, bool disponible) {
	this->descripcion = descripcion;
	this->codigo = codigo;
	clase_terminada = false;
	clase_pausada = true;
	en_accion = false;
	fuera_linea = disponible;
	//this->chat.set_lista_sockets_chat(&(this->sockets_chat));
	curso = 0;
}

unsigned int Clase::getCodigo() {
    return codigo;
}

std::string Clase::getDescripcion() {
	return descripcion;
}

std::list<Socket*>* Clase::getSocket_alumnos_av() {
    return &socket_alumnos_av;
}

void Clase::setSocket_Instr(Socket* socket_instructor_av) {
	this->socket_instructor_av = socket_instructor_av;
}

void Clase::setCodigo(unsigned int codigo) {
    this->codigo = codigo;
}

void Clase::inscribirAlumno(std::string nombre_Alumno) {
	this->alumnos_inscriptos.push_back(nombre_Alumno);
}

void Clase::agregarSocketAlumno_AV(Socket *socket_av) {
	this->socket_alumnos_av.push_back(socket_av);
}

void Clase::verInscriptos() {
	std::list<std::string>::iterator it;
	std::cout << "Alumnos inscriptos: " << std::endl;
	int aux = 0;
	for(it = alumnos_inscriptos.begin(); it != alumnos_inscriptos.end(); ++it) {
		aux++;
		std::cout << "Alumno " << aux << " : "  << it->c_str() << std::endl;
	}
}

// Recibe y envia frames
void Clase::run() {
	char buffer[TAM_BLOQUE_INI];
	char cod_op;
	int tam_arg = 0;
	std::string nom_arch;
	this->nombrarVideo(&nom_arch);
	std::ofstream arch(nom_arch.c_str());
	while((!clase_terminada) || (!clase_pausada)) {
		if(!(socket_instructor_av->recibir(buffer, 1))) {
			std::cerr << "Se desconecto el cliente" << std::endl;
			break;
		}
		cod_op = buffer[0];
		if((cod_op != 'V') && (cod_op != 'A')) {
			std::cerr << "Codigo de operacion invalido/Clase terminada" << std::endl;
			if (cod_op == 'Z') {
		    // Se envia el codigo del cierre al chat
			 // this->chat.enviar_codigo_fin_clase();
			}
			break;
		}
		if(!(socket_instructor_av->recibir(&buffer[1], 4))) {
			std::cerr << "Se desconecto el cliente" << std::endl;
			break;
		}
		tam_arg = *(unsigned int*)&buffer[1];
		memmove(buffer, &buffer[(TAM_BLOQUE_INI -1)], TAM_BLOQUE_INI - (TAM_BLOQUE_INI -1));
		char *argumentos = new char[tam_arg];
		if(tam_arg > 0) {
			if(!(socket_instructor_av->recibir(argumentos, tam_arg))) {
				std::cerr << "Se desconecto el cliente" << std::endl;
				delete[] argumentos;
				break;
			}
			for(it_socket = socket_alumnos_av.begin(); it_socket != socket_alumnos_av.end(); ++it_socket) {
				if(!(*it_socket)->enviar(&cod_op, sizeof(cod_op))) {
					std::cerr << "No se pudo enviar el codigo" << std::endl;
					//it_socket = socket_alumnos_av.erase(it_socket); // Elimna el socket de la lista
					break;
				}
				if(!(*it_socket)->enviar(&tam_arg, sizeof(tam_arg))) {
					std::cerr << "No se pudo enviar el tamanio" << std::endl;
					//it_socket = socket_alumnos_av.erase(it_socket); // Elimna el socket de la lista
					break;
				}
				if(!(*it_socket)->enviar(argumentos, tam_arg)) {
					std::cerr << "No se pudo enviar el bloque de argumentos" << std::endl;
					//it_socket = socket_alumnos_av.erase(it_socket); // Elimna el socket de la lista
					break;
				}
			}
			if(cod_op == 'V')
				arch.write(argumentos, tam_arg);
		}
		delete[] argumentos;
	}
}

unsigned int Clase::getCurso() {
	return curso;
}

void Clase::setCurso(unsigned int curso) {
	this->curso = curso;
}

void Clase::agregar_socket_chat(Socket* socket) {
// this->sockets_chat.push_back(socket);
}

void Clase::enviar_mensaje_al_chat(std::string nombre_usuario, std::string texto) {
 // this->chat.enviar_mensaje(nombre_usuario, texto);
}

void Clase::pausarClase() {
	clase_pausada = true;
}

void Clase::continuarClase() {
	clase_pausada = false;
}

void Clase::terminarClase() {
	clase_terminada = true;
}

void Clase::iniciarClase() {
	clase_terminada = false;
}

bool Clase::esta_Terminada() {
	return clase_terminada;
}

void Clase::agregarArchivo(std::string nom_arch) {
	this->adjuntos.push_back(nom_arch);
}

void Clase::nombrarVideo(std::string *nom_arch) {
	if(curso > 0) {
		*nom_arch = this->Int_toString(curso);
		*nom_arch += "_";
	}
	*nom_arch += this->Int_toString(codigo);
	*nom_arch += "_";
	*nom_arch += descripcion;
	*nom_arch += ".avi";
}

bool Clase::getDisponibilidad() {
	return fuera_linea;
}

// Busca si el alumno esta inscripto al curso
bool Clase::buscarAlumno(std::string nombre_alumno) {
	std::list<std::string>::iterator it;
	for(it = alumnos_inscriptos.begin(); it != alumnos_inscriptos.end(); it++) {
		if((*it).compare(nombre_alumno.c_str()) == 0) {
			return true;
		}
	}
	return false;
}

std::list<std::string>* Clase::getAdjuntos() {
	return &this->adjuntos;
}

std::string Clase::Int_toString(unsigned int entero) {
	std::string str;
	std::stringstream ss;
	ss << entero;
	ss >> str;
	return str;
}

Clase::~Clase() {}
